import xml.etree.ElementTree as ET
import xml.dom.minidom

class CToXML:
    
    def c_to_xml(self, xml_path, file_path):
        doc = ET.Element("cppcompare")
        with open(file_path, "r") as file:
            self.str_to_xml(file, doc)
        xml_string = ET.tostring(doc, encoding="utf-8").decode("utf-8")
        xml_dom = xml.dom.minidom.parseString(xml_string)
        formatted_xml = xml_dom.toprettyxml(indent="    ")  # 设置缩进为4个空格
        with open(xml_path, "w", encoding="utf-8") as xml_file:
            xml_file.write(formatted_xml) 
        
    def str_to_xml(self, sr, doc):
        tempEle = doc
        stack = []  # 用于模拟递归的堆栈
        for str1 in sr:
            str1 = str1.strip()
            if str1:
                if "{" in str1:
                    str_part = self.get_first_words(str1)
                    if "for" in str1 or "while" in str1:
                        if "for (" in str1:   # Convert for loop to Loop node
                            changeFor1 = ET.Element("Other")
                            changeFor2 = ET.Element("Other")
                            e = ET.Element("Loop")
                            if (str1.index(";") - str1.index("(")) != 1:
                                changeFor1.text = str1[str1.index("(") + 1:str1.index(";") - 1]
                                doc.append(changeFor1)
                            str2 = str1[str1.index(";") + 1:]
                            if str2[0] == ";":
                                e.set("Condition", "null")
                            else:
                                e.set("Condition", str2[:str2.index(";")])
                            if (str2.index(")") - str2.index(";")) != 1:
                                changeFor2.text = str2[str2.index(";") + 2:str2.index("{") - 3]
                                e.append(changeFor2)
                            doc.append(e)
                            tempEle = e
                        else:   # Convert while loop to Loop node
                            e = ET.Element("Loop")
                            e.set("Condition", str1[str1.index("(") + 1:str1.index(")") - 1])
                            doc.append(e)
                            tempEle = e
                    elif str1.strip() == "{":
                        e = ET.Element("block")
                        doc.append(e)
                        tempEle = e
                    elif  str1.startswith('if') or "else if" in str1:
                        if "{"in str1:
                            #continue
                        # 处理 if 或 else if 的情况
                            print(str1)
                            print("在")
                            e = ET.Element("Judge")
                            e.set("Judgement", str1[str1.index("(") + 1:str1.index("{") - str1.index("(") - 2])
                            tempEle.append(e)
                            tempEle = e
                        else:
                            continue
                    elif "switch" in str1:
                        # 处理 switch 的情况
                        e = ET.Element("Switch")
                        e.set("Judgement", str1[str1.index("(") + 1:str1.index(")") - str1.index("(") - 1])
                        tempEle.append(e)
                        tempEle = e
                    elif "case" in str1:
                        # 处理 case 的情况
                        e = ET.Element("Case")
                        tempEle.append(e)
                        tempEle = e


                    elif "struct" in str1:
                        # 处理 struct 的情况
                        e = ET.Element("Struct")
                        e.set("Name", str1[str1.index("struct") + 7:str1.index("{") - 1])
                        tempEle.append(e)
                        tempEle = e
                    else:
                        # 处理其他情况，如函数等
                        e = ET.Element("Function")
                        if "main" in str1:
                            e.set("ParaNum", "0")
                            e.set("Name", "main")
                        else:
                            para_count = str1.count(",") + 1 if "," in str1 else 0
                            e.set("ParaNum", str(para_count))
                            type_and_name = self.extract_function_type_and_name(str1)
                            if type_and_name:
                                e.set("Name", type_and_name[1])
                                e.set("Type", type_and_name[0])
                            else:
                                e.set("Name", "")
                                e.set("Type", "")
                        tempEle.append(e)
                        tempEle = e
                    stack.append(tempEle)
                        
                elif "}" in str1:
                    # 处理 } 的情况，回到上一层父元素
                    if stack:
                        tempEle = stack.pop()
                else:
                    # 处理其他情况，如变量等
                    str_word = self.get_first_words(str1)
                    if (str_word in ["int", "char", "short", "long", "double", "bool", "float"]) and ("(" not in str1):
                        e = ET.Element("variable")
                        e.set("Size", "")
                        e.set("Value", self.get_var_value(str1))
                        e.set("Name", self.get_var_name(str1))
                        e.set("Type", str_word)
                        if "[" in str1:  # 如果存在 [，则设置 Size 属性为 [ 后面的内容
                            e.set("Size", str1[str1.index("[") + 1 : str1.index("]")])
                        tempEle.append(e)
                    else:
                        e = ET.Element("Other")
                        e.text = str1
                        tempEle.append(e)
                    
                    
            else:
                print("chanage success")



        
    def extract_function_type_and_name(self, line):
        open_paren_index = line.find("(")
        if open_paren_index != -1:
            function_declaration = line[:open_paren_index].strip()
            last_space_index = function_declaration.rfind(" ")
            if last_space_index != -1:
                function_type = function_declaration[:last_space_index].strip()
                function_name = function_declaration[last_space_index + 1:]
                return function_type, function_name
        return None           
                
                
    def get_first_words(self, string):
        sb = []
        for char in string:
            if char != " " and char != "(":
                sb.append(char)
            else:
                break
        return "".join(sb)
    
    def get_var_value(self, string):
        sb = []
        if "=" in string:
            i = string.index("=")
            sb.append(string[i + 2 : len(string) - 1])
        return "".join(sb)
    
    def get_var_name(self, string):
        sb = []
        if "=" in string:
            i = len(self.get_first_words(string)) + 1
            j = string.index("=") - 2
            sb.append(string[i : j + 1])
        else:
            sb.append(string[len(self.get_first_words(string)) + 1 : len(string) - 1])
        return "".join(sb)
                

